package agent

import (
	"encoding/json"
	"fmt"
	"strings"
)

// JSONExtractor 负责从AI响应中提取JSON对象
type JSONExtractor struct{}

// NewJSONExtractor 创建新的JSON提取器
func NewJSONExtractor() *JSONExtractor {
	return &JSONExtractor{}
}

// ExtractJSON 从响应中提取JSON对象
func (je *JSONExtractor) ExtractJSON(content string) (map[string]interface{}, error) {
	// 清理响应内容
	content = strings.TrimSpace(content)

	// 首先尝试提取JSON对象，处理各种边界情况
	jsonContent := je.extractJSONFromResponse(content)
	if jsonContent == "" {
		return nil, fmt.Errorf("响应格式错误: 未找到JSON对象")
	}

	var response map[string]interface{}
	if err := json.Unmarshal([]byte(jsonContent), &response); err != nil {
		fmt.Printf("[DEBUG] JSON解析失败，原始内容: %s\n", je.truncateForError(jsonContent, 300))
		fmt.Printf("[DEBUG] 内容长度: %d\n", len(jsonContent))
		fmt.Printf("[DEBUG] 内容开头: %q\n", jsonContent[:je.min(50, len(jsonContent))])
		fmt.Printf("[DEBUG] 内容结尾: %q\n", jsonContent[je.max(0, len(jsonContent)-50):])
		return nil, fmt.Errorf("failed to parse JSON response: %v, content: %s", err, je.truncateForError(jsonContent, 200))
	}

	return response, nil
}

// extractJSONFromResponse 从响应中提取JSON对象，现在假设响应使用markdown代码块
func (je *JSONExtractor) extractJSONFromResponse(content string) string {
	content = strings.TrimSpace(content)

	// 查找代码块的开始
	startIdx := strings.Index(content, "```json")
	if startIdx == -1 {
		return ""
	} else {
		startIdx += 7 // 跳过 "```json"
	}

	// 跳过换行符
	if startIdx < len(content) && content[startIdx] == '\n' {
		startIdx++
	}

	// 查找结束代码块
	endIdx := strings.Index(content[startIdx:], "```")
	if endIdx == -1 {
		// 没有找到结束代码块，尝试直接提取JSON
		return je.extractJSONDirectly(content)
	}

	// 提取代码块内容并清理
	jsonContent := strings.TrimSpace(content[startIdx : startIdx+endIdx])

	// 确保内容是有效的JSON格式
	if !strings.HasPrefix(jsonContent, "{") || !strings.HasSuffix(jsonContent, "}") {
		return je.extractJSONDirectly(content)
	}

	return jsonContent
}

// extractJSONDirectly 直接提取JSON对象
func (je *JSONExtractor) extractJSONDirectly(content string) string {
	// 找到第一个 '{' 和最后一个 '}'
	startIdx := strings.Index(content, "{")
	endIdx := strings.LastIndex(content, "}")

	if startIdx == -1 || endIdx == -1 || startIdx >= endIdx {
		return strings.TrimSpace(content)
	}

	return strings.TrimSpace(content[startIdx : endIdx+1])
}

// truncateForError 截断字符串用于错误信息显示
func (je *JSONExtractor) truncateForError(s string, maxLen int) string {
	if len(s) <= maxLen {
		return s
	}
	return s[:maxLen] + "..."
}

// min 返回两个整数中的较小值
func (je *JSONExtractor) min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

// max 返回两个整数中的较大值
func (je *JSONExtractor) max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
